import sys
import os
import logging
from Readers import *
from Statistics import *
from hmmalgorithm import *
#############################
# FRAMEWORK TO START A GAME #
#############################

def default(str):
  return str + ' [Default: %default]'
  
LEVELS = {'debug': logging.DEBUG,
          'info': logging.INFO,
          'warning': logging.WARNING,
          'error': logging.ERROR,
          'critical': logging.CRITICAL}

  
def readCommand( argv ):
  """
  Processes the command used to run HMM from the command line.
  """
  from optparse import OptionParser
  usageStr = """
  USAGE:      python HMM.py <options>
  EXAMPLES:   (1) python HMM.py
                  - starts an interactive game
              (2) python HMM.py --layout smallClassic --zoom 2
              OR  python HMM.py -l smallClassic -z 2
                  - starts an interactive game on a smaller board, zoomed in
  """
  parser = OptionParser(usageStr)
  
  parser.add_option('-t', '--trainDir', dest='trainDir', type='string',
                    help=default('the training Set fasta file or directory of fasta files'), metavar='TRAIN_DIR', default="train")
  parser.add_option('-a', '--annotationDir', dest='annotationDir', type='string',
                    help=default('the annotation Directory of EMBOSS files'), metavar='ANNOTATION_DIR', default="annotations")
  parser.add_option('-s', '--testDir', dest='testDir', type='string',
                    help=default('the test Set fasta file or directory of fasta files'), metavar='TEST_DIR', default="test")
  parser.add_option('-m', '--metrics', dest='metrics', type='string',
                    help=default('Display Metrics, Yes or No'), default="Yes")
  parser.add_option('-l', '--logginglevel', dest='logginglevel', type='string',
                    help=default('logging level: debug info warning error critical'), default="info")
  parser.add_option('-u', '--unsupervised', action='store_true', dest='unsupervised',
                    help=default('unsupervised'), default=False)                    
  
  options, otherjunk = parser.parse_args(argv)
  if len(otherjunk) != 0: 
	raise Exception('Command line input not understood: ' + str(otherjunk))
  args = dict()
   
  
  # Choose a layout
  args['trainDir'] = options.trainDir
  args['testDir'] = options.testDir
  args['annotationDir'] = options.annotationDir
  args['metrics'] = options.metrics
  args['logginglevel'] = options.logginglevel
  args['unsupervised'] = options.unsupervised
  return args



    




if __name__ == '__main__':
  """
  The main function called when HMM.py is run
  from the command line:

  > python HMM.py

  See the usage string for more details.

  > python HMM.py --help
  """
  
  
  


  args = readCommand( sys.argv[1:] ) # Get game components based on input
  
  # Log everything, and send it to stderr.
  logging.basicConfig(level=LEVELS[args['logginglevel']])
  logging.debug( args['unsupervised'])
  logging.debug( args['annotationDir'])
  
  f = FastaReader()
  testSet = f.getTrainingData(args['testDir'])
  a = AnnotationReader()
  annotations = a.getAnnotationData(args['annotationDir'])

  trainingSet = f.getTrainingData(args['trainDir'])


  s = StatisticsCollector(trainingSet, annotations)
  
  outfile = open("output.txt", "w") 
  if args['unsupervised']:
    
    os.sys.path.append("lab3")
    import hmm
    hid = hmm.getHiddenStates(2)
    s.logAll()
    PI = dict()
    PI[0] = s.stateGiven["S"]["B"]
    PI[1] = s.stateGiven["S"]["I"]
    A = dict()
    for j, k in zip(["B", "I"], hid):
      A[k] = dict()
      for l, m in zip(["B", "I"], hid):
        A[k][m] = s.stateGiven[j][l]
    B = dict()
    for j, k in zip(["B", "I"], hid):
      B[k] = dict()
      for l in s.tokenGiven[j].keys():
        B[k][l] = s.tokenGiven[j][l]
    print PI
    print A
    print B 
    for name, v in testSet.items():
      sequence = v[0]
      print name
      import os
      obs = set()
      for c in sequence:
		  obs.add(c)
      A2, B2, PI2 = hmm.getBestModel(sequence, obs, hid, A, B, PI)
      hid_seq, score = hmm.viterbi(sequence,  hid, PI2, A2, B2)
      print "RESULT on " + name + ": " + hid_seq
      import Metrics
      outfile.write("Results on " + name + "\n\n" + Metrics.getCGPercents(hid_seq, hid, window=30) + "\n\n")

    #h = UnsupervisedHMM(s)
    #h.runHMM( testSet )
  else:
    h = HMM(s)
    #import cProfile
    
    for k, v in testSet.items():
      print k
      #h.run( "CGCGCGCGCGCGCGCGCGCGCGCGCGCGCGCGCGCGCGCGCGCGCGCGCGAATATATATATATAT" )
      #cProfile.run("h.run( s[0] )")
      print "RESULT on " + k + ": " + str(h.run( v[0] ))
      decode = h.getHiddenSequence()
      import Metrics
      outfile.write("Results on " + k + "\n\n"+ Metrics.getCGPercents(decode, ["B","I"], window=30) + "\n\n")
  print "Metrics have been written to \"output.txt\"\n"
